package cn.fz.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Tag(name = "用户登录管理",description = "用户登录管理")
@RestController
@RequestMapping("/user")
public class UserController {
    // 测试登录，浏览器访问： http://localhost:8081/user/doLogin?username=zhang&password=123456
    @Operation(summary = "登录接口")
    @RequestMapping(value = "doLogin",method = {RequestMethod.POST,RequestMethod.GET})
    public SaResult doLogin(String username, String password) {
        // 此处仅作模拟示例，真实项目需要从数据库中查询数据进行比对
        if ("asan".equals(username) && "123456".equals(password)){
            StpUtil.login(10001);
            return SaResult.ok("登录成功");
        }
        return SaResult.error("登录失败");
    }

    // 查询登录状态，浏览器访问： http://localhost:8081/user/isLogin
    @Operation(summary = "查询登录状态")
    @GetMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录：" + StpUtil.isLogin();
    }

    @Operation(summary = "注销当前登录会话")
    @GetMapping("logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok("请重新登录");
    }

    @Operation(summary = "检验当前会话是否已经登录")
    @GetMapping("checkLogin")
    public SaResult checkLogin() {
        // 检验当前会话是否已经登录, 如果未登录，则抛出异常：`NotLoginException`
        try {
            StpUtil.checkLogin();
        } catch (NotLoginException e) {
            // throw new RuntimeException(e);
            return SaResult.error(e.getMessage());
        }
        return SaResult.ok("当前会话已登录");
    }

    @Operation(summary = "会话查询与token查询")
    @GetMapping("getInfo")
    public SaResult getInfo(HttpServletRequest request) {
        Map<String,Object> map = new HashMap<>();
        map.put("loginId",StpUtil.getLoginId());
        map.put("tokenInfo",StpUtil.getTokenInfo());
        map.put("tokenValue",StpUtil.getTokenValue());
        map.put("tokenName",StpUtil.getTokenName());
        map.put("tokenTimeout",StpUtil.getTokenTimeout());
        map.put("requestCookie", Arrays.toString(request.getCookies()));
        return SaResult.data(map);
    }

    @Operation(summary = "获取当前账号所拥有的权限集合")
    @GetMapping("getPermissionList")
    public SaResult getPermissionList(HttpServletRequest request) {
        // 获取：当前账号所拥有的权限集合
        List<String> permissionList = StpUtil.getPermissionList();
        return SaResult.data(permissionList);
    }

    @Operation(summary = "判断或者校验当前账号是否包含指定权限")
    @Parameter(name = "type", description =
            "1:判断：当前账号是否含有指定权限, 返回 true 或 false;" +
            "2:校验：当前账号是否含有指定权限, 如果验证未通过，则抛出异常: NotPermissionException;" +
            "3:校验：当前账号是否含有指定权限 [指定多个，必须全部验证通过];" +
            "4:校验：当前账号是否含有指定权限 [指定多个，只要其一验证通过即可]")
    @Parameter(name = "val", description = "要校验的值如果有多个使用逗号分割")
    @PostMapping("getPermissionList")
    public SaResult getPermissionList(@RequestParam("type") Integer type,@RequestParam("val") String val) {
        Map<String,Object> map = new HashMap<>();
        map.put("type", type);
        map.put("val", val);
        map.put("result", true);
        if (type.equals(1)){
            // 判断：当前账号是否含有指定权限, 返回 true 或 false
            // map.put("result", StpUtil.hasPermission("user.add"));
            map.put("result", StpUtil.hasPermission(val));
        }else if(type.equals(2)) {
            // 校验：当前账号是否含有指定权限, 如果验证未通过，则抛出异常: NotPermissionException
            // try {
            //     // StpUtil.checkPermission("user.add");
            //     StpUtil.checkPermission(val);
            // } catch (Exception e) {
            //     map.put("result", false);
            //     map.put("message", e.getMessage());
            // }
            StpUtil.checkPermission(val);
        }else if (type.equals(3)){
            // 校验：当前账号是否含有指定权限 [指定多个，必须全部验证通过]
            // try {
            //     String[] split = val.split(",");
            //     // StpUtil.checkPermissionAnd("user.add", "user.delete", "user.get");
            //     StpUtil.checkPermissionAnd(split);
            // } catch (Exception e) {
            //     // throw new RuntimeException(e);
            //     map.put("result", false);
            //     map.put("message", e.getMessage());
            // }
            StpUtil.checkPermissionAnd(val.split(","));
        }else if (type.equals(4)){
            // try {
            //     // 校验：当前账号是否含有指定权限 [指定多个，只要其一验证通过即可]
            //     String[] split = val.split(",");
            //     StpUtil.checkPermissionOr(split);
            //     // StpUtil.checkPermissionOr("user.add", "user.delete", "user.get");
            //     map.put("result", true);
            // } catch (Exception e) {
            //     map.put("result", false);
            //     map.put("message", e.getMessage());
            // }
            StpUtil.checkPermissionOr(val.split(","));
        }else {
            throw new RuntimeException("type参数错误");
        }
        return SaResult.data(map);
    }

    @Operation(summary = "获取当前账号所拥有的角色集合")
    @GetMapping("getRoleList")
    public SaResult getRoleList(HttpServletRequest request) {
        // 获取：当前账号所拥有的角色集合
        List<String> roleList = StpUtil.getRoleList();
        return SaResult.data(roleList);
    }

    @Operation(summary = "踢人下线")
    @GetMapping("kickOut")
    public SaResult kickOut() {
        StpUtil.kickout(StpUtil.getLoginId());
        return SaResult.ok("踢人下线成功，请重新登录");
    }

    // 登录校验：只有登录之后才能进入该方法
    @Operation(summary = "查询用户信息")
    @GetMapping("info")
    public SaResult info() {
        if (StpUtil.isLogin()){
            return SaResult.data(StpUtil.getTokenInfo());
        }
        return SaResult.error("请先登录");
    }

    // 角色校验：必须具有指定角色才能进入该方法
    // @SaCheckRole("super-admin")

    @SaIgnore
    @Operation(summary = "新增用户信息")
    @GetMapping("add")
    public String add() {
        return "用户增加成功";
    }
}
